<template>
  <div>
    <h2>ChatGPT</h2>
    <div class="tool-box">
      <el-switch v-model="contextMode" active-color="#13ce66" active-text="开启上下文模式">
      </el-switch>
      <el-button type="primary" @click="clearMessageList">清空对话</el-button>
    </div>
    <div class="chat-box">
      <div class="message-rows">
        <div v-for="item in dataList.messageList" :key="item.index"
          :class="item.author === 'AI' ? 'message-row ai-class' : 'human-class'" ref="scrollDiv">
          <div class="avatar">
            <img
              :src="item.author === 'AI' ? 'http://20.205.38.73:10003/image/ai.svg' : 'http://20.205.38.73:10003/image/human.svg'"
              alt="" class="avatar">
          </div>
          <div class="message">
            <div :class="item.message === '...' ? 'loading-animation' : ''">{{ item.message }}</div>
          </div>
        </div>
      </div>
      <div class="inputBox">
        <el-input :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入 ..." maxlength="1000"
          v-model="dataList.inputMessage" @keydown.enter="keyDown" autofocus="true">
        </el-input>
      </div>
    </div>
    <div></div>
  </div>
</template>

<script setup>
import { ref, reactive, nextTick, watch } from 'vue'
import { getChatResponse } from '@/api/chat'

const contextMode = ref(false)
const scrollDiv = ref()
const lockFlag = ref(false)
const dataList = reactive({
  inputMessage: '',
  messageList: []
})
watch(
  () => dataList.messageList,
  (newVal) => {
    nextTick(() => {
      if (newVal.length > 0) {
        scrollDiv.value[newVal.length - 1].scrollIntoView()
      }
    })
  },
  {
    deep: true
  }
)
const clearMessageList = (e) => {
  dataList.messageList = []
}
const keyDown = (e) => {
  if (e.ctrlKey && e.keyCode === 13) {
    // ctrl+enter
    dataList.inputMessage = dataList.inputMessage + '\n'
    console.log(dataList.inputMessage)
  } else {
    // enter
    sendMessage()
  }
}

const sendMessage = () => {
  if (dataList.inputMessage.length !== 0) {
    if (!lockFlag.value) {
      lockFlag.value = true
      let prompt = 'The following is a conversation with an AI assistant. ' +
        'The assistant ishelpful, creative, clever, and very friendly.\n' +
        'Human: Hello, who are you?\n' +
        'AI: I am an AI created by OpenAI. How can I help you today?\n'
      if (!contextMode.value) {
        console.log('未开启上下文')
        prompt = prompt + 'Human: ' + dataList.inputMessage + '\nAI: '
      } else {
        console.log('开启上下文')
        for (let i = 0; i < dataList.messageList.length; i++) {
          prompt += dataList.messageList[i].author + ': ' + dataList.messageList[i].message + '\n'
        }
        prompt += 'Human: ' + dataList.inputMessage + '\nAI: '
      }
      console.log(contextMode)
      console.log(prompt)
      dataList.messageList.push({
        author: 'Human',
        message: dataList.inputMessage
      })
      dataList.messageList.push({
        author: 'AI',
        message: '...'
      })
      dataList.inputMessage = ''
      getChatResponse(prompt)
        .then((res) => {
          lockFlag.value = false
          const text = res.data.text
          dataList.messageList[dataList.messageList.length - 1] = {
            author: 'AI',
            message: text
          }
        })
        .catch((rej) => {
          lockFlag.value = false
          console.log('rej', rej)
        })
      // dataList.messageList.forEach((item, index) => {
      //   if (index === 0) {
      //     _context = _context.concat(item.message + "/n/n");
      //   } else {
      //     _context = _context.concat(item.author + ":" + item.message + "/n");
      //   }
      // });
      // console.log("input:", _context);
      // let url = 'http://127.0.0.1:8000/novalai/chat_gpt_v1/';
      // let data = {'prompt': prompt}
      // axios({
      //   url,
      //   data: qs.stringify(data),
      //   method: 'post',
      //   headers: {
      //     'Content-Type': 'application/x-www-form-urlencoded'
      //   }
      // }).then(res => {
      //   console.log(res)
      //   lockFlag.value = false;
      //   const text = res.data.text;
      //   dataList.messageList[dataList.messageList.length - 1] = {
      //     author: "AI",
      //     message: text,
      //   };
      // })
    }
  }
}
</script>

<style scoped>
.tool-box {
  display: flex;
  justify-content: space-around;
}

.chat-box {
  margin: 0 auto;
  height: 70vh;
  display: flex;
  justify-content: center;
}

.message-rows {
  width: 100%;
  overflow-y: auto;
}

.message-row {
  display: flex;
  justify-content: center;
}

.ai-class {
  background-color: rgba(247, 247, 248);
  display: flex;
  width: 100%;
  padding: 20px 0 20px 0;
  justify-content: center;
  align-items: flex-start;
}

.human-class {
  background-color: #ffffff;
  display: flex;
  width: 100%;
  padding: 20px 0 20px 0;
  justify-content: center;
  align-items: flex-start;
}

@keyframes blink {

  from,
  to {
    border-color: transparent;
  }

  50% {
    border-color: #a11ec6;
  }
}

.message {
  font-size: 1rem;
  line-height: 1.5rem;
  width: min(700px, 95vw);
  min-height: 20px;
  text-align: left;
  margin-left: 10px;
  white-space: pre-wrap;
}

.ai-class .loading-animation {
  display: inline-block;
  overflow: hidden;
  animation: blink 0.75s step-end infinite;
  border-right: 4px solid #a11ec6;
  box-sizing: border-box;
}

.avatar {
  width: 1rem;
  height: 1rem;
  margin: 2px 0 0 5px;
}

/*.human-class .message-row:before {*/
/*  position: absolute;*/
/*  display: block;*/
/*  content: '';*/
/*  background-image: url("http://20.205.38.73:10003/image/human.svg");*/
/*  background-size: 100% 100%;*/
/*  margin-left: -30px;*/
/*  width: 20px;*/
/*  height: 20px;*/
/*}*/

/*.ai-class .message-row:before {*/
/*  position: absolute;*/
/*  display: block;*/
/*  content: '';*/
/*  background-image: url("http://20.205.38.73:10003/image/ai.svg");*/
/*  background-size: 100% 100%;*/
/*  margin-left: -30px;*/
/*  width: 20px;*/
/*  height: 20px;*/
/*}*/

.inputBox {
  width: min(600px, 90vw);
  position: fixed;
  bottom: 5vh;
  left: 50%;
  margin-left: max(-300px, -45vw);
}
</style>
